/*! \file _kru.h
	\brief Private header used by K&R Unit library.
	\warning Do not use this header outside of the library.
*/

#include <setjmp.h>
#include <time.h>

/*! \brief Internal representation of a test.
*/
struct kru_test
{
	/*! The next test in the list of tests. */
	/*@dependent@*/ kru_test *next;
	/*@shared@*/ kru_suite *suite;
	/*@owned@*/ /*@null@*/ char* name;
	/*@null@*/ kru_test_setup_proc setup;
	/*@notnull@*/ kru_test_fixture test;
	/*@null@*/ kru_test_teardown_proc teardown;
	int asserts;
	int setups;
	int setupSuccesses;
	int setupFailures;
	int runs;
	int successes;
	int failures;
	int teardowns;
	int teardownSuccesses;
	int teardownFailures;
	/*! This is used for non-local jumps in case of fatal test failures */
	jmp_buf jbuf;
	/*@null@*/ const char *errorMessage;
	/*! The test's start time. */
	clock_t start;
	/*! The test's stop time. */
	clock_t stop;
};

/*! \brief Internal representation of a test suite.
*/
struct kru_suite
{
	/*! The next element of the suites list. */
	/*@dependent@*/ kru_suite *next;
	/*@shared@*/ kru_registry *registry;
	/*@owned@*/ /*@null@*/ char *name;
	/*@null@*/ kru_suite_setup_proc setup;
	/*@owned@*/ /*@null@*/ kru_test *head;
	/*! The pointer to the last element of the list (for ordered insertion). */
	/*@dependent@*/ /*@null@*/ kru_test *tail;
	/*@null@*/ kru_suite_teardown_proc teardown;
	/*@null@*/ void *testData;
	int setups;
	int setupSuccesses;
	int setupFailures;
	int runs;
	int successes;
	int failures;
	int teardowns;
	int teardownSuccesses;
	int teardownFailures;
};

/*! \struct kru_registry
	\brief Internal representation of the tests registry.

	The list of the test suites organized in the same
	manner as the list of tests.
*/
struct kru_registry
{
	/*@owned@*/ /*@null@*/ kru_suite *head;
	/*@dependent@*/ /*@null@*/ kru_suite *tail;
	/*@owned@*/ /*@null@*/ char *name;
	/*@notnull@*/ kru_format_proc format;
};

/*! \brief Tests statistics.

	This structure contains all statistics on the test run and
	used to generate the run report.
*/
typedef struct
{
	// Test data
	int testAsserts;
	int testSetups;
	int testSetupSuccesses;
	int testSetupFailures;
	int testRuns;
	int testSuccesses;
	int testFailures;
	int testTeardowns;
	int testTeardownSuccesses;
	int testTeardownFailures;
	// Suite data
	int suiteSetups;
	int suiteSetupSuccesses;
	int suiteSetupFailures;
	int suiteRuns;
	int suiteSuccesses;
	int suiteFailures;
	int suiteTeardowns;
	int suiteTeardownSuccesses;
	int suiteTeardownFailures;
	// Registry data
	int registryTotalSuites;
	int registryTotalTests;
	double registryRunTime;
} kru_stat;

/*! \fn char* dupstring(const char *string)
	\brief A _strdup replacement for internal use.
	\param string - A string to duplicate.
 */
/*@null@*/ extern char* dupstring(const char *string);
